package com.md2ppt.presentation;

import com.md2ppt.config.PresentationConfig;
import com.md2ppt.animation.AnimationEngine;
import com.aspose.slides.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.awt.Color;
import java.util.Map;

/**
 * 演示文稿构建器
 * 负责创建和配置PowerPoint演示文稿
 */
public class PresentationBuilder {
    
    private static final Logger logger = LoggerFactory.getLogger(PresentationBuilder.class);
    
    private final PresentationConfig config;
    private final AnimationEngine animationEngine;
    private final SlideFactory slideFactory;
    private final ContentRenderer contentRenderer;
    
    private int processedSlides = 0;
    private long totalProcessingTime = 0;
    private int totalAnimations = 0;
    
    public PresentationBuilder(PresentationConfig config, AnimationEngine animationEngine) {
        this.config = config;
        this.animationEngine = animationEngine;
        this.slideFactory = new SlideFactory();
        this.contentRenderer = new ContentRenderer();
        
        logger.info("初始化演示文稿构建器");
    }
    
    /**
     * 构建完整演示文稿
     */
    public IPresentation build() throws Exception {
        logger.info("开始构建演示文稿: {}", config.metadata().title());
        
        var presentation = new Presentation();
        
        try {
            // 设置演示文稿属性
            configurePresentationProperties(presentation);
            
            // 移除默认空白幻灯片
            if (presentation.getSlides().size() > 0) {
                presentation.getSlides().removeAt(0);
            }
            
            // 创建所有幻灯片
            for (var slideConfig : config.slides()) {
                var startTime = System.currentTimeMillis();
                
                var slide = createSlide(presentation, slideConfig);
                
                var processingTime = System.currentTimeMillis() - startTime;
                totalProcessingTime += processingTime;
                processedSlides++;
                
                logger.info("完成幻灯片 {} ({}ms)", slideConfig.index(), processingTime);
            }
            
            logger.info("演示文稿构建完成: {} 张幻灯片", processedSlides);
            return presentation;
            
        } catch (Exception e) {
            logger.error("演示文稿构建失败", e);
            presentation.dispose();
            throw e;
        }
    }
    
    /**
     * 配置演示文稿属性
     */
    private void configurePresentationProperties(IPresentation presentation) {
        // 设置文档属性
        var properties = presentation.getDocumentProperties();
        properties.setTitle(config.metadata().title());
        properties.setAuthor(config.metadata().author());
        properties.setCreatedTime(new java.util.Date());
        
        // 设置幻灯片尺寸（16:9）
        presentation.getSlideSize().setSize(1920, 1080, SlideSizeScaleType.DoNotScale);
        
        logger.debug("配置演示文稿属性完成");
    }
    
    /**
     * 创建单张幻灯片
     */
    private ISlide createSlide(IPresentation presentation, PresentationConfig.SlideConfig slideConfig) {
        // 创建幻灯片
        var slide = slideFactory.createSlide(presentation, slideConfig);
        
        // 渲染内容元素
        if (slideConfig.content() != null) {
            for (var contentElement : slideConfig.content()) {
                contentRenderer.renderContent(slide, contentElement);
            }
        }
        
        // 应用动画
        if (slideConfig.animations() != null && !slideConfig.animations().isEmpty()) {
            animationEngine.applyAnimations(slide, slideConfig.animations());
            totalAnimations += slideConfig.animations().size();
        }
        
        return slide;
    }
    
    /**
     * 保存演示文稿
     */
    public void save(IPresentation presentation, Path outputPath) throws Exception {
        logger.info("保存演示文稿到: {}", outputPath);
        
        var startTime = System.currentTimeMillis();
        
        // 根据质量设置保存选项
        var saveOptions = createSaveOptions();
        
        presentation.save(outputPath.toString(), SaveFormat.Pptx, saveOptions);
        
        var saveTime = System.currentTimeMillis() - startTime;
        logger.info("演示文稿保存完成 ({}ms)", saveTime);
    }
    
    /**
     * 创建保存选项
     */
    private PptxOptions createSaveOptions() {
        var options = new PptxOptions();
        
        // 根据质量级别设置压缩
        switch (config.settings().quality().toUpperCase()) {
            case "HIGH":
                options.setCompressionLevel(CompressionLevel.NotCompressed);
                logger.debug("使用高质量设置");
                break;
            case "LOW":
                options.setCompressionLevel(CompressionLevel.Maximum);
                logger.debug("使用低质量设置");
                break;
            default:
                options.setCompressionLevel(CompressionLevel.Normal);
                logger.debug("使用普通质量设置");
                break;
        }
        
        return options;
    }
    
    /**
     * 获取构建统计信息
     */
    public BuildStatistics getStatistics() {
        var avgTime = processedSlides > 0 ? totalProcessingTime / processedSlides : 0;
        return new BuildStatistics(processedSlides, totalAnimations, avgTime);
    }
    
    /**
     * 构建统计记录
     */
    public record BuildStatistics(
        int slideCount,
        int animationCount,
        long avgProcessingTimePerSlide
    ) {}
    
    /**
     * 幻灯片工厂
     */
    private static class SlideFactory {
        
        public ISlide createSlide(IPresentation presentation, PresentationConfig.SlideConfig slideConfig) {
            // 选择布局模板
            var layoutSlide = selectLayoutSlide(presentation, slideConfig.layout());
            
            // 添加幻灯片
            var slide = presentation.getSlides().addSlide(layoutSlide);

            // 设置标题
            setSlideTitle(slide, slideConfig.title());
            
            // 应用背景
            if (slideConfig.layout() != null && slideConfig.layout().background() != null) {
                applyBackground(slide, slideConfig.layout().background());
            }
            
            return slide;
        }
        
        private ILayoutSlide selectLayoutSlide(IPresentation presentation, PresentationConfig.SlideLayout layout) {
            // 默认使用标题和内容布局
            var masterSlide = presentation.getMasters().get_Item(0);
            return masterSlide.getLayoutSlides().get_Item(1); // Title and Content
        }
        
        private void setSlideTitle(ISlide slide, String title) {
            if (title != null && !title.trim().isEmpty()) {
                // 查找标题占位符
                for (var shape : slide.getShapes()) {
                    if (shape.getPlaceholder() != null && 
                        shape.getPlaceholder().getType() == PlaceholderType.Title) {
                        var textFrame = ((IAutoShape) shape).getTextFrame();
                        textFrame.setText(title);
                        break;
                    }
                }
            }
        }
        
        private void applyBackground(ISlide slide, Map<String, Object> background) {
            if (background.containsKey("color")) {
                var colorHex = (String) background.get("color");
                var color = Color.decode(colorHex);
                slide.getBackground().setType(BackgroundType.OwnBackground);
                slide.getBackground().getFillFormat().setFillType(FillType.Solid);
                slide.getBackground().getFillFormat().getSolidFillColor().setColor(color);
            }
        }
    }
    
    /**
     * 内容渲染器
     */
    private static class ContentRenderer {
        
        public void renderContent(ISlide slide, PresentationConfig.ContentElement element) {
            switch (element.type().toLowerCase()) {
                case "text" -> renderTextContent(slide, element);
                case "image" -> renderImageContent(slide, element);
                case "video" -> renderVideoContent(slide, element);
                case "shape" -> renderShapeContent(slide, element);
                default -> LoggerFactory.getLogger(ContentRenderer.class)
                                       .warn("不支持的内容类型: {}", element.type());
            }
        }
        
        private void renderTextContent(ISlide slide, PresentationConfig.ContentElement element) {
            var data = element.data();
            var text = (String) data.get("text");
            
            if (text != null) {
                var shape = slide.getShapes().addAutoShape(
                    ShapeType.Rectangle,
                    (float) element.position().x(),
                    (float) element.position().y(),
                    (float) element.position().width(),
                    (float) element.position().height()
                );
                
                shape.getTextFrame().setText(text);
                shape.getFillFormat().setFillType(FillType.NoFill);
                shape.getLineFormat().setFillType(FillType.NoFill);
            }
        }
        
        private void renderImageContent(ISlide slide, PresentationConfig.ContentElement element) {
            var data = element.data();
            var imagePath = (String) data.get("path");
            
            if (imagePath != null) {
                try {
                    var image = slide.getPresentation().getImages().addImage(
                        new java.io.FileInputStream(imagePath)
                    );
                    
                    slide.getShapes().addPictureFrame(
                        ShapeType.Rectangle,
                        (float) element.position().x(),
                        (float) element.position().y(),
                        (float) element.position().width(),
                        (float) element.position().height(),
                        image
                    );
                } catch (Exception e) {
                    LoggerFactory.getLogger(ContentRenderer.class)
                                 .error("图像加载失败: {}", imagePath, e);
                }
            }
        }
        
        private void renderVideoContent(ISlide slide, PresentationConfig.ContentElement element) {
            var data = element.data();
            var videoPath = (String) data.get("path");
            
            if (videoPath != null) {
                try {
                    var video = slide.getPresentation().getVideos().addVideo(
                        new java.io.FileInputStream(videoPath)
                    );
                    
                    slide.getShapes().addVideoFrame(
                        (float) element.position().x(),
                        (float) element.position().y(),
                        (float) element.position().width(),
                        (float) element.position().height(),
                        video
                    );
                } catch (Exception e) {
                    LoggerFactory.getLogger(ContentRenderer.class)
                                 .error("视频加载失败: {}", videoPath, e);
                }
            }
        }
        
        private void renderShapeContent(ISlide slide, PresentationConfig.ContentElement element) {
            // 根据形状类型创建对应的形状
            var data = element.data();
            var shapeType = (String) data.get("shape_type");
            
            Integer asposeShapeType;
            String normalizedShapeType = shapeType != null ? shapeType.toLowerCase() : "rectangle";
            switch (normalizedShapeType) {
                case "circle":
                    asposeShapeType = ShapeType.Ellipse;
                    break;
                case "triangle":
                    asposeShapeType = ShapeType.Triangle;
                    break;
                default:
                    asposeShapeType = ShapeType.Rectangle;
                    break;
            }
            
            slide.getShapes().addAutoShape(
                asposeShapeType,
                (float) element.position().x(),
                (float) element.position().y(),
                (float) element.position().width(),
                (float) element.position().height()
            );
        }
    }
}